@includeNamed{'common-lib.templ'}

@declare{'genPropFromJson'}
	@if{property.list || property.set}
	@{indent}if (json.getValue("@{property.name}") instanceof JsonArray) {\n
		@if{property.adder}
			@{indent}  json.getJsonArray("@{property.name}").forEach(item -> {\n
			@{indent}    if (item instanceof @{cast})\n
			@{indent}      obj.@{property.adderMethod}(@{before}item@{after});\n
			@{indent}  });\n
		@else{property.setter}
			@code{coll = property.list ? 'java.util.ArrayList' : 'java.util.HashSet'}
			@{indent}  @{coll}<@{propType.name}> list = new @{coll}<>();\n
			@{indent}  json.getJsonArray("@{property.name}").forEach( item -> {\n
			@{indent}    if (item instanceof @{cast})\n
			@{indent}      list.add(@{before}item@{after});\n
			@{indent}  });\n
			@{indent}  obj.@{property.setterMethod}(list);\n
		@end{}
	@{indent}}\n
	@else{property.map}
		@if{property.setter}
			@{indent}if (json.getValue("@{property.name}") instanceof JsonObject) {\n
				@{indent}  java.util.Map<String, @{propType.name}> map = new java.util.LinkedHashMap<>();\n
				@{indent}  json.getJsonObject("@{property.name}").forEach(entry -> {\n
				@{indent}    if (entry.getValue() instanceof @{cast})\n
				@{indent}      map.put(entry.getKey(), @{before}entry.getValue()@{after});\n
				@{indent}  });\n
				@{indent}  obj.@{property.setterMethod}(map);\n
			@{indent}}\n
		@end{}
	@else{}
		@if{property.setter}
			@{indent}if (json.getValue("@{property.name}") instanceof @{cast}) {\n
				@{indent}  obj.@{property.setterMethod}(@{before}json.getValue("@{property.name}")@{after});\n
			@{indent}}\n
		@end{}
	@end{}
@end{}

@code{

  def computeConverterClassJavadoc(type) {
    var builder = new StringBuilder();
    builder.append(" *").append(" Converter for {@link ").append(type).append("}.");
    builder.append("\n *\n * NOTE: This class has been automatically generated from the {@link " + type + "} original class using Vert.x codegen.");
    return builder.append("\n").toString();
  }
}


/*\n
 * Copyright 2014 Red Hat, Inc.\n
 *\n
 * Red Hat licenses this file to you under the Apache License, version 2.0\n
 * (the "License"); you may not use this file except in compliance with the\n
 * License.  You may obtain a copy of the License at:\n
 *\n
 * http://www.apache.org/licenses/LICENSE-2.0\n
 *\n
 * Unless required by applicable law or agreed to in writing, software\n
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\n
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n
 * License for the specific language governing permissions and limitations\n
 * under the License.\n
 */\n\n
package @{type.packageName};\n
\n
import io.vertx.core.json.JsonObject;\n
import io.vertx.core.json.JsonArray;\n
\n
/**\n
@{computeConverterClassJavadoc(type.name)}
 */\n
public class @{type.simpleName}Converter {\n
\n
  public static void fromJson(JsonObject json, @{type.simpleName} obj) {\n
		@foreach{property:properties}
			@if{property.declared || inheritConverter}
				@code{propType=property.type}
				@code{propKind=propType.kind}
				@if{propKind == CLASS_API}
					@if{propType.name == 'io.vertx.core.buffer.Buffer'}
						@includeNamed{'genPropFromJson';cast='String';before='io.vertx.core.buffer.Buffer.buffer(java.util.Base64.getDecoder().decode((String)';after='))';indent='    '}
					@end{}
				@else{propKind == CLASS_JSON_OBJECT}
					@includeNamed{'genPropFromJson';cast='JsonObject';before='((JsonObject)';after=').copy()';indent='    '}
				@else{propKind == CLASS_JSON_ARRAY}
					@includeNamed{'genPropFromJson';cast='JsonArray';before='((JsonArray)';after=').copy()';indent='    '}
				@else{propKind.basic}
					@if{propKind == CLASS_STRING}
						@includeNamed{'genPropFromJson';cast='String';before='(String)';after='';indent='    '}
					@else{}
						@if{propType.simpleName == 'boolean' || propType.simpleName == 'Boolean'}
							@includeNamed{'genPropFromJson';cast='Boolean';before='(Boolean)';after='';indent='    '}
						@else{propType.simpleName == 'byte' || propType.simpleName == 'Byte'}
							@includeNamed{'genPropFromJson';cast='Number';before='((Number)';after=').byteValue()';indent='    '}
						@else{propType.simpleName == 'short' || propType.simpleName == 'Short'}
							@includeNamed{'genPropFromJson';cast='Number';before='((Number)';after=').shortValue()';indent='    '}
						@else{propType.simpleName == 'int' || propType.simpleName == 'Integer'}
							@includeNamed{'genPropFromJson';cast='Number';before='((Number)';after=').intValue()';indent='    '}
						@else{propType.simpleName == 'long' || propType.simpleName == 'Long'}
							@includeNamed{'genPropFromJson';cast='Number';before='((Number)';after=').longValue()';indent='    '}
						@else{propType.simpleName == 'float' || propType.simpleName == 'Float'}
							@includeNamed{'genPropFromJson';cast='Number';before='((Number)';after=').floatValue()';indent='    '}
						@else{propType.simpleName == 'double' || propType.simpleName == 'Double'}
							@includeNamed{'genPropFromJson';cast='Number';before='((Number)';after=').doubleValue()';indent='    '}
						@else{propType.simpleName == 'char' || propType.simpleName == 'Character'}
							@includeNamed{'genPropFromJson';cast='String';before='((String)';after=').charAt(0)';indent='    '}
						@end{}
					@end{}
				@else{propKind == CLASS_DATA_OBJECT}
					@includeNamed{'genPropFromJson';cast='JsonObject';before='new ' + propType.name + '((JsonObject)';after=')';indent='    '}
				@else{propKind == CLASS_ENUM}
					@includeNamed{'genPropFromJson';cast='String';before='' + propType.name + '.valueOf((String)';after=')';indent='    '}
				@else{propKind == CLASS_OBJECT}
					@includeNamed{'genPropFromJson';cast='Object';before='';after='';indent='    '}
				@end{}
			@end{}
		@end{}
  }\n

@declare{'genPropToJson'}
	@if{property.list || property.set}
		@{indent}if (obj.@{property.getterMethod}() != null) {\n
		@{indent}  json.put("@{property.name}", new JsonArray(\n
		@{indent}      obj.@{property.getterMethod}().\n
		@{indent}          stream().\n
		@{indent}          map(item -> @{before}item@{after}).\n
		@{indent}          collect(java.util.stream.Collectors.toList())));\n
		@{indent}}\n
	@else{property.map}
		@{indent}if (obj.@{property.getterMethod}() != null) {\n
		@{indent}  JsonObject map = new JsonObject();\n
		@{indent}  obj.@{property.getterMethod}().forEach((key,value) -> map.put(key, @{before}value@{after}));\n
		@{indent}  json.put("@{property.name}", map);\n
		@{indent}}\n
	@else{}
		@if{property.type.kind != CLASS_PRIMITIVE}@{indent}if (obj.@{property.getterMethod}() != null) {\n  @end{}
		@{indent}json.put("@{property.name}", @{before}obj.@{property.getterMethod}()@{after});\n
		@if{property.type.kind != CLASS_PRIMITIVE}@{indent}}\n@end{}
	@end{}
@end{}

\n
  public static void toJson(@{type.simpleName} obj, JsonObject json) {\n
		@foreach{property:properties}
			@if{(property.declared || inheritConverter) && property.getterMethod != null && property.jsonifiable}
				@code{propType=property.type}
				@code{propKind=propType.kind}
				@if{propKind == CLASS_API}
					@if{propType.name == 'io.vertx.core.buffer.Buffer'}
						@includeNamed{'genPropToJson';before='';after='.getBytes()';indent='    '}
					@end{}
				@else{propKind == CLASS_ENUM}
					@includeNamed{'genPropToJson';before='';after='.name()';indent='    '}
				@else{propKind == CLASS_JSON_OBJECT || propKind == CLASS_JSON_ARRAY}
					@includeNamed{'genPropToJson';before='';after='';indent='    '}
				@else{propKind.basic}
					@if{propKind == CLASS_STRING || propKind == CLASS_JSON_OBJECT || propKind == CLASS_JSON_ARRAY}
						@includeNamed{'genPropToJson';before='';after='';indent='    '}
					@else{propType.simpleName == 'char' || propType.simpleName == 'Character'}
						@includeNamed{'genPropToJson';before='Character.toString(';after=')';indent='    '}
					@else{}
						@includeNamed{'genPropToJson';before='';after='';indent='    '}
					@end{}
				@else{propKind == CLASS_DATA_OBJECT}
					@includeNamed{'genPropToJson';before='';after='.toJson()';indent='    '}
				@else{propKind == CLASS_OBJECT}
					@includeNamed{'genPropToJson';before='';after='';indent='    '}
				@end{}
			@end{}
		@end{}
  }\n
}